# 在函数嵌套的嵌套下， 内部函数使用了外部函数的变量，并且外部函数返回了内部函数 --- 把使用外部函数变量的内部函数称为闭包

# 定义一个简单的闭包
# def say_hello(name):
#     def say(msg):
#         name = '李四' # 在内部函数里面定义了一个局部变量 只是名称相同而已
#         print(f'对着{name}说{msg}')
#     print(name)
#     say('hello')
#     print(name)
#     return say
#
# if __name__ == '__main__':
#     # sa就是闭包
#     sa = say_hello('张三')
#     # sa('你好吗？')
#     # sa('在干嘛')

# 修改外部变量
# def say_hello(name):
#     def say(msg):
#         nonlocal name  # 告诉解释器，name 是外部函数的变量
#         name = '李四'  # 在内部函数里面定义了一个局部变量 只是名称相同而已
#         print(f'对着{name}说{msg}')
#
#     print(name)
#     say('hello')
#     print(name)
#     return say
#
#
# if __name__ == '__main__':
#     # sa就是闭包
#     sa = say_hello('张三')
#     # sa('你好吗？')
#     # sa('在干嘛')


# 装饰器

# 需要先登录，才能发布评论
# 为了给comment加一个额外功能 定义一个装饰器

# def login(func):  # 参数必须是一个函数
#     print('装饰器开始执行')
#
#     def inner():
#         print('检查是否登录，如果没有则登录')
#         func()
#
#     return inner
#
# @login
# def comment():
#     print('发布评论')
#
#
# # com = login(comment)
# # com()
# comment()

# 装饰器类的写法(了解)
# class Login(object):  # 参数必须是一个函数
#     def __init__(self, func):
#         self.func = func
#
#     def __call__(self, *args, **kwargs):
#         print('检查是否登录，如果没有则登录')
#         return self.func(*args, **kwargs)
#
#
# @Login
# def comment():
#     print('发布评论')
#
# if __name__ == '__main__':
#     print(comment)
#     comment()


# property 装饰器 把函数当作属性去使用  当作来操作私有属性
class Person(object):

    def __init__(self):
        self.__age = 0

    @property
    def age(self):
        print('调用了age函数')
        return self.__age

    @age.setter  # 该装饰器：把age当成属性了，但是只能用于给age赋值
    def age(self,x_age):
        print('调用设置__age属性的函数')
        self.__age = x_age


if __name__ == '__main__':
    p = Person()
    p.age = 10
    a = p.age
    print(a)
